home *** CD-ROM | disk | FTP | other *** search
-
- #include "RealWoofStream.h"
-
- #include "MemMgr.h"
-
- #include "Debug.h"
- #include "MoreMacTCP.h"
- #include "WoofURL.h"
- #include "BufferManager.h"
-
-
-
- #define INHERITED TRealCyberStream
-
- #define kMinBuffersAreLow 50 // buffers are no longer low when this percentage is reached
- #define kMaxBuffersAreLow 75 // buffers are low when this percentage is reached
- #define kMaxReadThreshold 90 // when we have this much of MacTCP's buffer space, stop posting reads
-
- TRealWoofStream::TRealWoofStream()
- {
- fDoggieTalk = nil;
- fImmediateBuffer = nil;
- fImmediateBufferLength = 0;
- fClientNotifier = nil;
- fOnHold = false;
- fNameText = nil;
- fNameLength = 0;
- fOpen = false;
- fImmediate = false;
- }
-
-
-
- TRealWoofStream::~TRealWoofStream()
- {
- if (fNameText)
- {
- MMFree((Ptr)fNameText);
- ASSERT(!MemError());
- fNameText = nil;
- }
- if (fImmediateBuffer)
- {
- MMFree((Ptr)fImmediateBuffer);
- ASSERT(!MemError());
- fImmediateBuffer = nil;
- }
-
- // delete fBufferManager; ???
- }
-
-
- void TRealWoofStream::GetSynchronousData(char* buffer, Size* bufferLength)
- {
- Boolean foundProcess;
- ProcessSerialNumber process;
- ProcessInfoRec infoRec;
- OSErr result;
- FSSpec processFSSpec;
- Str31 tempStr;
- int i;
- long tempNum;
-
- *bufferLength = 0;
-
- process.highLongOfPSN = 0;
- process.lowLongOfPSN = kNoProcess;
- infoRec.processInfoLength = sizeof(ProcessInfoRec);
- infoRec.processName = (StringPtr) tempStr;
- infoRec.processAppSpec = &processFSSpec;
-
- while ((result = GetNextProcess(&process)) == noErr)
- {
- result = GetProcessInformation(&process, &infoRec);
- if (result != noErr)
- break;
-
- if (EqualString((ConstStr255Param) infoRec.processName, (ConstStr255Param) fNameText, false, true))
- break;
- }
-
- if ((result != noErr) && (result != procNotFound))
- fStreamError = result;
-
- if (result == noErr)
- {
- i = 0;
-
- BlockMove("Process Info for \"", buffer, 24);
- i += 24;
- BlockMove(tempStr+1, buffer+i, tempStr[0]);
- i += tempStr[0];
- BlockMove("\"\n", buffer+i, 2);
- i += 2;
-
- BlockMove("\nProcess Serial Number: ", buffer+i, 24);
- i += 24;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0xF0000000) >> 28;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0x0F000000) >> 24;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0x00F00000) >> 20;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0x000F0000) >> 16;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0x0000F000) >> 12;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0x00000F00) >> 8;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.highLongOfPSN & 0x000000F0) >> 4;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = infoRec.processNumber.highLongOfPSN & 0x0000000F;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0xF0000000) >> 28;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0x0F000000) >> 24;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0x00F00000) >> 20;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0x000F0000) >> 16;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0x0000F000) >> 12;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0x00000F00) >> 8;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processNumber.lowLongOfPSN & 0x000000F0) >> 4;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = infoRec.processNumber.lowLongOfPSN & 0x0000000F;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
-
- BlockMove("\nProcess Type: ", buffer+i, 24);
- i += 24;
- BlockMove(&infoRec.processType, buffer+i, 4);
- i += 4;
-
- BlockMove("\nProcess Creator: ", buffer+i, 24);
- i += 24;
- BlockMove(&infoRec.processSignature, buffer+i, 4);
- i += 4;
-
- BlockMove("\nProcess Mode: ", buffer+i, 24);
- i += 24;
- tempNum = (infoRec.processMode & 0xF0000000) >> 28;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processMode & 0x0F000000) >> 24;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processMode & 0x00F00000) >> 20;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processMode & 0x000F0000) >> 16;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processMode & 0x0000F000) >> 12;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processMode & 0x00000F00) >> 8;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processMode & 0x000000F0) >> 4;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = infoRec.processMode & 0x0000000F;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
-
- BlockMove("\nProcess Location: ", buffer+i, 24);
- i += 24;
- tempNum = (((unsigned long) infoRec.processLocation) & 0xF0000000) >> 28;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (((unsigned long) infoRec.processLocation) & 0x0F000000) >> 24;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (((unsigned long) infoRec.processLocation) & 0x00F00000) >> 20;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (((unsigned long) infoRec.processLocation) & 0x000F0000) >> 16;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (((unsigned long) infoRec.processLocation) & 0x0000F000) >> 12;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (((unsigned long) infoRec.processLocation) & 0x00000F00) >> 8;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (((unsigned long) infoRec.processLocation) & 0x000000F0) >> 4;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = ((unsigned long) infoRec.processLocation) & 0x0000000F;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
-
- BlockMove("\nProcess Size: ", buffer+i, 24);
- i += 24;
- NumToString(infoRec.processSize, tempStr);
- BlockMove(tempStr+1, buffer+i, tempStr[0]);
- i += tempStr[0];
-
- BlockMove("\nProcess Free Mem: ", buffer+i, 24);
- i += 24;
- NumToString(infoRec.processFreeMem, tempStr);
- BlockMove(tempStr+1, buffer+i, tempStr[0]);
- i += tempStr[0];
-
- BlockMove("\nProcess Launched By: ", buffer+i, 24);
- i += 24;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0xF0000000) >> 28;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0x0F000000) >> 24;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0x00F00000) >> 20;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0x000F0000) >> 16;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0x0000F000) >> 12;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0x00000F00) >> 8;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.highLongOfPSN & 0x000000F0) >> 4;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = infoRec.processLauncher.highLongOfPSN & 0x0000000F;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0xF0000000) >> 28;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0x0F000000) >> 24;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0x00F00000) >> 20;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0x000F0000) >> 16;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0x0000F000) >> 12;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0x00000F00) >> 8;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = (infoRec.processLauncher.lowLongOfPSN & 0x000000F0) >> 4;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
- tempNum = infoRec.processLauncher.lowLongOfPSN & 0x0000000F;
- *(buffer+(i++)) = (tempNum < 10) ? '0' + tempNum : 'A' + tempNum - 10;
-
- /*
- BlockMove("\nProcess Launch Time: ", buffer+i, 24);
- i += 24;
- DateString((long) infoRec.processLaunchDate, abbrevDate, (StringPtr) tempStr, nil);
- BlockMove(tempStr+1, buffer+i, tempStr[0]);
- i += tempStr[0];
- BlockMove(" ", buffer+i, 2);
- i += 2;
- TimeString((long) infoRec.processLaunchDate, true, (StringPtr) tempStr, nil);
- BlockMove(tempStr+1, buffer+i, tempStr[0]);
- i += tempStr[0];
- */
-
- BlockMove("\nProcess Active Time: ", buffer+i, 24);
- i += 24;
- NumToString(infoRec.processActiveTime, tempStr);
- BlockMove(tempStr+1, buffer+i, tempStr[0]);
- i += tempStr[0];
- BlockMove(" ticks\n", buffer+i, 24);
-
- *bufferLength = i;
- }
- }
-
-
- void TRealWoofStream::DoggieNotifier(unsigned short eventCode, Ptr buffer, Size bufferSize, OSErr result, void* userDataPtr)
- {
- TRealWoofStream* THIS = (TRealWoofStream*) userDataPtr;
- Environment* ev = somGetGlobalEnvironment();
-
- THIS->DoggieProcessEvent(ev, eventCode, buffer, bufferSize, result);
- }
-
-
- void TRealWoofStream::DoggieProcessEvent(Environment* ev, unsigned short eventCode, Ptr buffer, Size bufferSize, OSErr result)
- {
- if (eventCode == kDoggieClosed)
- {
- // The connection was closed. This means the server has finished sending data.
- fStreamStatus |= kDownloadComplete;
-
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kDownloadCompleteEvent, this, fClientUserData);
-
- this->Abort(ev);
- }
- else if (eventCode == kDoggieDoneRead)
- {
- fBufferManager->AddBuffer(buffer, bufferSize);
-
- if (!(fStreamStatus & kDataAvailable))
- {
- fStreamStatus |= kDataAvailable;
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kDataAvailableEvent, this, fClientUserData);
- }
-
- //if (!(fStreamStatus & kBuffersAreLow) && (doggiebuffersarelow))
- if (!(fStreamStatus & kBuffersAreLow) && false)
- {
- fStreamStatus |= kBuffersAreLow;
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kBuffersAreLowEvent, this, fClientUserData);
- }
-
- //if (fBufferManager->OKToAddBuffer() && (doggiebuffersnotrunout))
- if (fBufferManager->OKToAddBuffer() && true)
- {
- // Post another read if the buffer manager can add the buffer and
- // we aren't holding most of protocol's buffer space
- //fDoggieTalk->Read();
- }
- else
- {
- fOnHold = true;
- }
- }
- else if (eventCode == kDoggieError)
- {
- // There was an error, so abort the connection!
- ASSERT(result != noErr);
- fStreamError = result;
- fStreamStatus |= kErrorOccurred;
- fStreamStatus |= kDownloadComplete;
-
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kErrorEvent, this, fClientUserData);
-
- this->Abort(ev);
- }
- }
-
-
- OSErr TRealWoofStream::Initialize(char* url)
- {
- OSErr result = noErr;
- unsigned short hostNameLen;
- unsigned short procNameLen;
- char* hostName;
- char* procName;
-
- // Initialize fields
-
- fStreamStatus = 0;
- fStreamSize = kStreamSizeUnknown;
- fStreamError = noErr;
-
- // Process URL
- ParseWoofURL(url, &hostName, &hostNameLen, &procName, &procNameLen);
-
- if (!procNameLen)
- return memFullErr;
-
- // get the name
- fNameLength = procNameLen;
- fNameText = (char*) MMAllocate(fNameLength + 1); // +1 for pascal string length •Err
- if (!fNameText)
- return memFullErr;
- BlockMove(procName, fNameText + 1, procNameLen);
- fNameText[0] = procNameLen;
-
- if (hostNameLen)
- {
- // Create the connection thingie
- fDoggieTalk = new TDoggieTalkConnection;
- fBufferManager = new TBufferManager;
- if (!fDoggieTalk || !fBufferManager)
- return memFullErr;
-
- result = fBufferManager->Initialize(kArbitraryBufferSize,
- (BufferManagerProcPtr) TRealWoofStream::ContinueReading,
- this);
- if (result != noErr)
- return result;
-
- // %%% get the host address and make an address thing here
- }
- else
- {
- fImmediate = true;
-
- fImmediateBuffer = (char*) MMAllocate(kArbitraryBufferSize);
- if (fImmediateBuffer)
- return memFullErr;
- fImmediateBufferLength = kArbitraryBufferSize;
- }
-
- return result;
- }
-
-
-
- OSErr TRealWoofStream::OpenWithCallback(Environment* ev, CyberStreamNotifyUPP callback, void* userData)
- {
- OSErr err;
-
- fClientNotifier = callback;
- fClientUserData = userData;
-
- err = this->Open(ev);
-
- return err;
- }
-
-
- OSErr TRealWoofStream::Open(Environment* ev)
- {
- if (!fOpen)
- {
- if (fImmediate)
- {
- this->GetSynchronousData(fImmediateBuffer, &fImmediateBufferLength);
-
- if (fStreamError)
- {
- fStreamStatus |= kErrorOccurred;
- fStreamStatus |= kDownloadComplete;
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kErrorEvent, this, fClientUserData);
-
- this->Abort(ev);
- }
- else
- {
- fStreamStatus |= kDataAvailable;
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kDataAvailableEvent, this, fClientUserData);
- }
- }
- else
- {
- ;//fDoggieTalk->Initialize((CyberDoggiePNotifyProcPtr) TRealWoofStream::DoggieNotifier, this);
- }
-
- fOpen = true;
- }
- return noErr;
- }
-
-
- void TRealWoofStream::GetBuffer(Environment* ev, Ptr* buffer, Size* bufferSize)
- {
- Size bytesProcessed = 0;
-
- *buffer = nil;
- *bufferSize = 0;
-
- if (fStreamStatus & kDataAvailable)
- {
- if (fImmediate)
- {
- *buffer = (Ptr) fImmediateBuffer;
- *bufferSize = fImmediateBufferLength;
-
- // and end it
- fStreamStatus = kDownloadComplete;
- if (fClientNotifier)
- CallCyberStreamNotifyProc(fClientNotifier, kDownloadCompleteEvent, this, fClientUserData);
-
- this->Abort(ev);
- }
- else
- {
- ASSERT(!fBufferManager->Empty());
-
- // Process the data and return it to the client
- // Do we need to take out CRLF from bufferSize?
- fBufferManager->RemoveBuffer(buffer, bufferSize);
-
- // if there are no more elements, clear the dataAvailable flag
- if (fBufferManager->Empty())
- {
- fStreamStatus ^= kDataAvailable;
- }
-
- // if we were on hold because protocol was out of queue elements,
- // we should try again
- if (fOnHold)
- {
- fOnHold = false;
- //fDoggieTalk->Read();
- }
- }
- }
- }
-
-
-
- void TRealWoofStream::ReleaseBuffer(Environment* /* ev */, Ptr buffer)
- {
- //fDoggieTalk->ReleaseBuffer(buffer);
-
- //if ((fStreamStatus & kBuffersAreLow) && (doggiebuffersnotrunout))
- if ((fStreamStatus & kBuffersAreLow) && true)
- {
- // if the user no longer has too many buffers, clear the flag
- fStreamStatus ^= kBuffersAreLow;
- //fDoggieTalk->Read();
- }
-
- // if we were on hold because MacTCP or the buffer manager was out of queue elements,
- // we should try again if we can
- else if (fOnHold && (fBufferManager->OKToAddBuffer()))
- {
- fOnHold = false;
- //fDoggieTalk->Read();
- }
- }
-
-
-
- StreamStatus TRealWoofStream::GetStreamStatus(Environment* /* ev */)
- {
- return fStreamStatus;
- }
-
-
-
- short TRealWoofStream::GetTotalDataSize(Environment* /* ev */)
- {
- return fStreamSize;
- }
-
-
-
- OSErr TRealWoofStream::GetStreamError(Environment* /* ev */)
- {
- return fStreamError;
- }
-
-
-
- void TRealWoofStream::Abort(Environment* /* ev */)
- {
- // fDoggieTalk->Abort();
- }
-
-
-
- void TRealWoofStream::GetStatusString(Environment* /* ev */, char* message)
- {
- BlockMove("\pNot yet implemented", message, 19);
- }
-
-
- // Called when the buffer manager thinks it is OK to start reading again
- void TRealWoofStream::ContinueReading(void* userData, OSErr result)
- {
- TRealWoofStream* THIS = (TRealWoofStream*) userData;
-
- if (result != noErr)
- {
- THIS->fStreamStatus |= kErrorOccurred;
- if (THIS->fClientNotifier)
- CallCyberStreamNotifyProc(THIS->fClientNotifier, kErrorEvent, THIS, THIS->fClientUserData);
- }
-
- else if (THIS->fOnHold)
- {
- THIS->fOnHold = false;
- //THIS->fDoggieTalk-Read();
- }
- }
-
-